package icantalk.voip;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Secondary class used for creating and parsing UDP datagrams
 *
 * @author Antonín Brettšnajdr
 */
public class PacketFactory {

    private static byte OR = (byte) '|';
    private static byte[] data;
    private static int length;
    private static ByteArrayOutputStream timestampBAOS;
    private static ByteArrayOutputStream seqBAOS;
    private static ByteArrayOutputStream dataBAOS;
    private static long sequence = 0;

    public static DatagramPacket createPacket(long timestamp, byte[] data, InetSocketAddress address) throws SocketException {
        char[] cstamp = (String.valueOf(timestamp) + "|" + String.valueOf(sequence++) + "|").toCharArray();

        byte[] b = new byte[cstamp.length + data.length];

        int i = 0;
        for (; i < cstamp.length; i++) {
            b[i] = (byte) cstamp[i];
        }

        for (int j = 0; j < data.length; j++) {
            b[i++] = data[j];
        }

        return new DatagramPacket(b, b.length, address);

    }

    public static Packet parsePacket(DatagramPacket p) {

        data = p.getData();

        if (new String(data).startsWith("CONN")) return null;

        length = p.getLength();

        timestampBAOS = new ByteArrayOutputStream();
        seqBAOS = new ByteArrayOutputStream();
        dataBAOS = new ByteArrayOutputStream();

        for (int i = 0; i < length; i++) {

            if (data[i] == OR) {

                for (i++; i < length; i++) {

                    if (data[i] == OR) {
                        for (i++; i < length; i++) {
                            dataBAOS.write((int) data[i]);
                        }
                    } else {
                        seqBAOS.write((int) data[i]);
                    }
                }
            } else {
                timestampBAOS.write((int) data[i]);
            }
        }

        try {
            timestampBAOS.close();
            seqBAOS.close();
            dataBAOS.close();
        } catch (IOException ex) {
            Logger.getLogger(PacketFactory.class.getName()).log(Level.SEVERE, null, ex);
        }

        return new Packet(Long.parseLong(new String(timestampBAOS.toByteArray())), Long.parseLong(new String(seqBAOS.toByteArray())) ,dataBAOS.toByteArray());
    }

}
